package com.hud.easynavi;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.Region;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

/**
 * Created by Administrator on 2017/2/23.
 */
public class ArcProgressView extends View  {
    Context ctx;
    boolean isEmulated = false;
    String TAG = "OilPanelView";
    private Paint paint_arc2;
    ArcParameterBuilder progress_arc1;
    ArcParameterBuilder progress_arc2;
    ArcParameterBuilder border1;
    ArcParameterBuilder border2;
    Path path;
    Paint pathTextPaint;
    float textSize = 10.0f;
    float arc1_k = 0.95f;
    float arc2_k = 0.70f;
    float hOffset = 0f; // 水平偏移
    float vOffset = 0f; // 垂直偏移
    int width = 144;
    int height = 35;
    int paddingTop = 18;

    SurfaceHolder holder;
    // RenderDrawThread drawThread;
    private float max_value = 100f;
    private float min_value = 0f;
    private float progress_value = 90f;// 当前进度
    private boolean showTextInfo = true;

//    @Override
//    public void surfaceCreated(SurfaceHolder surfaceHolder) {
//        Log.d(TAG,"surfaceCreated");
//        //drawThread.isRun = true;
//        //drawThread.start();
//    }
//
//    @Override
//    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
//        Log.d(TAG,"surfaceChanged");
//    }
//
//    @Override
//    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
//        // drawThread.isRun =false;
//        Log.d(TAG,"surfaceDestroyed");
//    }

    class DefaultConfigParam{
        float textSize = 20.0f;
        float arc_k1 = 0.5f;
        float arc_k2 = 0.4f;
        int fillColor = Color.GREEN;
        int borderColor = Color.WHITE;
        int bgColor = Color.BLACK;

        int topPadding = 0;
        int bottomPadding = 0;
        int leftPadding = 0;
        int rightPadding = 0;
    }

    public void setArc1_k(float k){
        this.arc1_k = k;
        progress_arc1.setK(k);
        border1.setK(k);
        invalidate();
    }

    public void setArc2_k(float k){
        this.arc2_k = k;
        progress_arc2.setK(k);
        border2.setK(k);
        invalidate();
    }

    public void setMaxProgress(float max){
        max_value = max;
        invalidate();
    }

    public void setMinProgress(float min){
        min_value = min;
        invalidate();
    }

    public void showTextInfo(boolean b){
        showTextInfo = b;
        invalidate();
    }

    public void setProgressValue(float value){
        progress_value = value;
        float angle = (180.0f * value) / max_value;
        sweep_angle = angle;
        progress_arc1.setSweepAngle(sweep_angle);
        invalidate();
    }

    public void setEmulated(boolean b){
        isEmulated = b;
    }

    public void setWidth(int w){
        this.width = w;
    }

    public void setHeight(int h){
        this.height = h;
    }

    public void setPanelBoxPaddingTop(int t){
        this.paddingTop = t;
        invalidate();
    }

    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            if(msg.what==0){
                invalidate();
            }
            //handler.sendEmptyMessageDelayed(0,100);
        }
    };

    public ArcProgressView(Context context) {
        super(context);
        init();
        ctx = context;
    }

    public ArcProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
        ctx = context;
    }

    public ArcProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
        ctx = context;
    }

    void init(){
//        holder = getHolder();
//        holder.addCallback(this);
        // drawThread = new RenderDrawThread(holder);
        path = new Path();
        paint_arc2 = new Paint();
        paint_arc2.setColor(Color.RED);
        paint_arc2.setStrokeWidth(1.0f);
        paint_arc2.setTextSize(textSize);
        paint_arc2.setAntiAlias(true);
        paint_arc2.setStyle(Paint.Style.STROKE);

        progress_arc1 = new ArcParameterBuilder();
        progress_arc1.setK(arc1_k);
        progress_arc1.setColor(Color.YELLOW);

        progress_arc2 = new ArcParameterBuilder();
        progress_arc2.setK(arc2_k);
        progress_arc2.setColor(Color.CYAN);

        border1 = new ArcParameterBuilder();
        border1.setK(arc1_k);
        border1.setColor(Color.WHITE);

        border2 = new ArcParameterBuilder();
        border2.setK(arc2_k);
        border2.setColor(Color.WHITE);

        pathTextPaint = new Paint();
        pathTextPaint.setColor(Color.GREEN);
        pathTextPaint.setStyle(Paint.Style.STROKE);
        pathTextPaint.setAntiAlias(true);
        pathTextPaint.setTextSize(textSize);
        pathTextPaint.setStrokeWidth(1.0f);

        handler.sendEmptyMessageDelayed(1000,100);
    }

    class RenderDrawThread extends Thread{
        private SurfaceHolder holder ;
        public  boolean isRun = false;

        public RenderDrawThread(SurfaceHolder holder){
            this.holder = holder;
            isRun = true;
            Log.i(TAG,"RenderDrawThread set surface holder");
        }

        @Override
        public void run(){
            Canvas canvas = null;
            while (isRun && !isInterrupted()) {
                try {
                    synchronized (holder) {
                        canvas = holder.lockCanvas();// 锁定画布，一般在锁定后就可以通过其返回的画布对象Canvas，在其上面画图等操作了。
                        performDrawing(canvas);
                    }
                    Thread.sleep(10);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (canvas != null) {
                        holder.unlockCanvasAndPost(canvas);// 结束锁定画图，并提交改变。
                    }
                }
            }
        }
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec,heightMeasureSpec);
        if(this.ctx.getResources().getConfiguration().getLayoutDirection()
                == Configuration.ORIENTATION_LANDSCAPE){ // 横屏
            // Log.d(TAG,"横屏----");
        }else{
            //Log.d(TAG,"竖屏----");
        }
        setMeasuredDimension(getMeasuredWidth(),getMeasuredHeight());
    }

    float sweep_angle = 0f;
    float path_text_sweep_angle = 20f;
    boolean increase = true;

    @Override
    public void onDraw(Canvas canvas) {
        performDrawing(canvas);
    }

    private void performDrawing(Canvas canvas){
        if(canvas==null)
            return;
        canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG|Paint.ANTI_ALIAS_FLAG));
        long start = System.currentTimeMillis();
        drawBg(canvas);

        RectF rectF = new RectF(0,0 + paddingTop,getWidth(),getHeight() + paddingTop);
        progress_arc1.setRect(rectF);
        progress_arc1.cal_param();

        progress_arc2.setRect(rectF);
        progress_arc2.cal_param();
//
        Path path = new Path();
        path.arcTo(progress_arc2.left,
                progress_arc2.top + 1,
                progress_arc2.right,
                progress_arc2.bottom + 1,
                180,
                180,
                false);
        canvas.clipPath(path, Region.Op.DIFFERENCE);

        if(showTextInfo){
            //绘制文字
            float txt_start_angle = 180 + sweep_angle;
            if(sweep_angle > 130){
                txt_start_angle = 180 + 130;
            }
            if(sweep_angle < 50){
                txt_start_angle = 180 + 50;
            }
            Path pathForText = new Path();
            pathForText.addArc(progress_arc1.left,
                    progress_arc1.top,
                    progress_arc1.right,
                    progress_arc1.bottom,
                    txt_start_angle,
                    90);
            canvas.drawTextOnPath(String.format("%03.1f %n",progress_value),pathForText,0,-3,pathTextPaint);
        }

        progress_arc1.drawArc(canvas);
        //progress_arc2.drawArc(canvas);

        // 绘制边框
        border1.setRect(rectF);
        border1.setStyle(Paint.Style.STROKE);
        border1.setSweepAngle(180);
        border1.cal_param();

        border2.setStyle(Paint.Style.STROKE);
        border2.setRect(rectF);
        border2.setSweepAngle(180);
        border2.cal_param();

        border1.drawArc(canvas);
        border2.drawArc(canvas);
        // canvas.drawRect(rectF.left,rectF.top,rectF.right,rectF.bottom,paint_arc2);
        long end = System.currentTimeMillis();
        // Log.d(TAG,+(end-start) * 1000 +" FPS");

        if(isEmulated){
            if(sweep_angle >= 180){
                increase = false;
            }else if(sweep_angle <=0){
                increase = true;
            }

            if(increase){
                sweep_angle += 1;
            }else{
                sweep_angle -= 1;
            }
        }

        if(sweep_angle > 150){
            pathTextPaint.setColor(Color.GREEN);
            progress_arc1.setColor(Color.GREEN);
        }

        if(sweep_angle < 80){
            pathTextPaint.setColor(Color.RED);
            progress_arc1.setColor(Color.RED);
        }

        if(sweep_angle < 150 && sweep_angle > 80){
            pathTextPaint.setColor(Color.parseColor("#ff9601"));
            progress_arc1.setColor(Color.parseColor("#ff9601"));
        }

        progress_arc1.setSweepAngle(sweep_angle);
    }

    void drawBg(Canvas c){
        c.drawColor(Color.BLACK);
    }

    static class ArcParameterBuilder
    {
        public int left,top,right,bottom;
        public double w,h;
        public double d,r,k = 0.5f;// k 参数决定弧度的弯曲程度
        RectF rectF;
        PointF pt;
        double sweep_angle = 0f;
        double sweep_angle_max = 180f;
        Paint paint;

        public ArcParameterBuilder(RectF baseRec){
            rectF = baseRec;
            init();
        }

        public ArcParameterBuilder(){
            init();
        }

        void init(){
            sweep_angle = 0f;
            paint = new Paint(Color.BLUE);
            paint.setStyle(Paint.Style.FILL);
            paint.setStrokeWidth(0.5f);
            paint.setAntiAlias(true);
            pt = new PointF();
        }

        public ArcParameterBuilder setRect(RectF rect){
            rectF = rect;
            return this;
        }

        public ArcParameterBuilder setK(double k_rate){
            k = k_rate;
            return this;
        }

        public ArcParameterBuilder setColor(int c){
            paint.setColor(c);
            return this;
        }

        public ArcParameterBuilder setStyle(Paint.Style s){
            paint.setStyle(s);
            return this;
        }

        public ArcParameterBuilder setSweepAngle(float angle){
            this.sweep_angle = angle;
            return this;
        }

        boolean already_calc_params = false;

        public void cal_param()
        {
            if(k<0)
                k=0.1f;

            d = rectF.height() * k;
            h =  rectF.height();
            w =  rectF.width();

            sweep_angle_max = 180;
            left = (int)rectF.left;
            top = (int)(rectF.top+(h-d));
            right = (int)(rectF.right);
            bottom = (int)(rectF.bottom+d);

            already_calc_params =true;
        }

        public void drawArc(Canvas canvas)
        {

            if(!already_calc_params)
                return;

            RectF oval = new RectF(left,top,right,bottom);
            // canvas.drawRect(left,top,right,bottom,paint);

            double start_angle = 180;
            canvas.drawArc(oval,(float)start_angle,(float)sweep_angle,true,paint);

            pt.x = (float) (  oval.left + d * Math.cos(sweep_angle));
            pt.y = (float) (  oval.top + h + d *( Math.cos(sweep_angle) -1));
        }
    }
}
